package com.fast.server.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fast.server.component.RedisComponent;
import com.fast.server.config.session.SessionWebUserConfig;
import com.fast.server.config.sysconfig.AppConfig;
import com.fast.server.config.toemail.RegisterToSendEmails;
import com.fast.server.config.userspace.UserSpaceConfig;
import com.fast.server.entity.constants.Constants;
import com.fast.server.entity.enums.RespBeanEnum;
import com.fast.server.entity.pages.UserPageParams;
import com.fast.server.entity.responseVO.RespBean;
import com.fast.server.entity.vo.SysUser;
import com.fast.server.exception.BusinessException;
import com.fast.server.mapper.SysUserMapper;
import com.fast.server.service.ISysFileShareService;
import com.fast.server.service.ISysUserService;
import com.fast.server.service.ISysVerificationCodeService;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 *
 * @author ziyuancheng
 * @since 2024-05-05
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private ISysVerificationCodeService verificationCodeMapper;
    @Resource
    private AppConfig appConfig;
    @Resource
    private ISysFileShareService fileInfoService;
    @Resource
    private RedisComponent redisComponent;

    @Override
    public SysUser getUserById(String userId) {
        return userMapper.selectById(userId);
    }

    @Override
    public RespBean updateUserById(String userId, SysUser sysUser) {
        int rows = userMapper.updateById(sysUser);
        if (rows != 1) return RespBean.error(RespBeanEnum.UPDATE_FILED);
        return RespBean.success(RespBeanEnum.UPDATE_CODE_200);
    }

    @Override
    public RespBean deleteUserById(String userId) {
        int rows = userMapper.deleteById(userId);
        if (rows != 1) return RespBean.error(RespBeanEnum.DELETE_FILED);
        return RespBean.success(RespBeanEnum.DELETE_CODE_200);
    }

    @Override
    public SysUser getUserByEmail(String email) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("email", email); // 使用邮箱进行查询
        return userMapper.selectOne(queryWrapper);
    }

    @Override
    public RespBean updateUserByEmail(String email, SysUser sysUser) {
        // 构建更新条件
        UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("email", email); // 根据邮箱进行更新

        // 执行更新操作
        int rows = userMapper.update(sysUser, updateWrapper);

        // 根据更新结果返回相应的响应
        if (1 != rows) return RespBean.error(RespBeanEnum.UPDATE_FILED);
        return RespBean.success(RespBeanEnum.UPDATE_CODE_200);
    }

    @Override
    public RespBean deleteUserByEmail(String email) {
        // 构建删除条件
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("email", email); // 根据邮箱进行删除

        // 执行删除操作
        int rows = userMapper.delete(queryWrapper);

        // 根据删除结果返回相应的响应
        if (rows != 1) return RespBean.error(RespBeanEnum.DELETE_FILED);
        return RespBean.success(RespBeanEnum.DELETE_CODE_200);
    }

    @Override
    public SysUser getUserByQQOpenId(String qqOpenId) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("qq_open_id", qqOpenId); // 使用QQ openID进行查询
        return userMapper.selectOne(queryWrapper);
    }

    @Override
    public RespBean updateUserByQQOpenId(String qqOpenId, SysUser sysUser) {
        // 构建更新条件
        UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("qq_open_id", qqOpenId); // 使用QQ openID进行更新

        // 执行更新操作
        int rows = userMapper.update(sysUser, updateWrapper);

        // 根据更新结果返回相应的响应
        if (1 != rows) return RespBean.error(RespBeanEnum.UPDATE_FILED);
        return RespBean.success(RespBeanEnum.UPDATE_CODE_200);
    }

    @Override
    public RespBean deleteUserByQQOpenId(String qqOpenId) {
        // 构建删除条件
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("qq_open_id", qqOpenId); // 使用QQ openID进行删除

        // 执行删除操作
        int rows = userMapper.delete(queryWrapper);

        // 根据删除结果返回相应的响应
        if (rows != 1) return RespBean.error(RespBeanEnum.DELETE_FILED);
        return RespBean.success(RespBeanEnum.DELETE_CODE_200);
    }

    @Override
    public SysUser getUserByWechatId(String wechatId) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("wechat_id", wechatId); // 使用微信ID进行查询
        return userMapper.selectOne(queryWrapper);
    }

    @Override
    public RespBean updateUserByWechatId(String wechatId, SysUser sysUser) {
        // 构建删除条件
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("wechat_id", wechatId); //使用微信ID进行更新

        // 执行删除操作
        int rows = userMapper.delete(queryWrapper);

        // 根据删除结果返回相应的响应
        if (rows != 1) return RespBean.error(RespBeanEnum.DELETE_FILED);
        return RespBean.success(RespBeanEnum.DELETE_CODE_200);
    }

    @Override
    public RespBean deleteUserByWechatId(String wechatId) {
        // 构建删除条件
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("wechat_id", wechatId); // 使用微信ID进行删除

        // 执行删除操作
        int rows = userMapper.delete(queryWrapper);

        // 根据删除结果返回相应的响应
        if (rows != 1) return RespBean.error(RespBeanEnum.DELETE_FILED);
        return RespBean.success(RespBeanEnum.DELETE_CODE_200);
    }

    @Override
    public RespBean getAllUsersByPage(UserPageParams pageParams) {
        // 构建分页对象
        Page<SysUser> page = new Page<>(pageParams.getPageNum(), pageParams.getPageSize());
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1); // 使用微信ID进行删除
        // 执行分页查询
        IPage<SysUser> userPage = userMapper.selectPage(page, queryWrapper);
        // 返回分页结果
        return RespBean.success(userPage);
    }

    @Override
    public RespBean addUser(SysUser user) {
        user.setUserId(UUID.randomUUID().toString());
        int rows = userMapper.insert(user);
        if (rows != 1) return RespBean.error(RespBeanEnum.ADD_FILED);
        return RespBean.success(RespBeanEnum.ADD_CODE_200);
    }

    @Override
    public RespBean addUsers(List<SysUser> userList) {
        if (ObjUtil.isNotEmpty(userList)) {
            for (SysUser user : userList) {
                user.setUserId(UUID.randomUUID().toString());
            }
            boolean rows = userMapper.saveBatch(userList);
            if (!rows) return RespBean.error(RespBeanEnum.ADD_FILED);
            return RespBean.success(RespBeanEnum.ADD_CODE_200);
        } else return RespBean.error(RespBeanEnum.ADD_FILED);
    }

    @Override
    public RespBean getUserAvatar(String userId) {
        // 根据用户 ID 查询用户信息
        SysUser user = userMapper.selectById(userId);
        if (ObjUtil.isNotEmpty(user)) {
            // 获取用户头像信息
            String userAvatar = user.getUserAvatar();
            return RespBean.success(userAvatar);
        } else {
            return RespBean.error(RespBeanEnum.AVATAR_FILED);
        }
    }

    @Override
    public RespBean getUserSpace(String userId) {
        // 查询用户空间信息，这里假设用户空间信息存储在数据库的 use_space 字段中
        SysUser user = userMapper.selectById(userId);
        if (user != null) {
            Long useSpace = user.getUseSpace();
            Long totalSpace = user.getTotalSpace();
            long[] space = {useSpace, totalSpace};
            // 返回用户空间信息
            return RespBean.success(space);
        } else {
            return RespBean.error(RespBeanEnum.SPACE_FILED);
        }
    }

    @Override
    public RespBean updateUserAvatar(String userId, String avatarUrl) {
        // 更新用户头像信息，这里假设用户头像信息存储在数据库的 user_avatar 字段中
        SysUser user = userMapper.selectById(userId);
        if (ObjUtil.isNotEmpty(user)) {
            user.setUserAvatar(avatarUrl);
            int rows = userMapper.updateById(user);
            if (rows == 0) {
                return RespBean.error(RespBeanEnum.UPDATE_FILED);
            } else {
                return RespBean.success(RespBeanEnum.UPDATE_CODE_200);
            }
        } else {
            return RespBean.error(RespBeanEnum.OBJECT_FILED);
        }
    }

    @Override
    public RespBean qqLogin(String qqOpenId) {
        // 根据 QQ OpenID 查询用户信息，这里假设用户信息中存储了 QQ OpenID
        SysUser user = userMapper.selectOne(new QueryWrapper<SysUser>().eq("qq_open_id", qqOpenId));
        return RespBean.success(user);
    }

    @Override
    public RespBean qqLoginCallback(String code) {
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void register(String email, String nickName, String password, String emailCode) {
        SysUser userInfo = getUserByEmail(email);
        if (ObjUtil.isNotEmpty(userInfo)) {
            throw new BusinessException("邮箱账号已经存在");
        }
        SysUser nickNameUser = userMapper.selectByNickName(nickName);
        if (ObjUtil.isNotEmpty(nickNameUser)) {
            throw new BusinessException("昵称已经存在");
        }
        //校验邮箱验证码
        verificationCodeMapper.checkCode(email, emailCode);
        String userId = RandomUtil.randomString(Constants.RANK_10);
        SysUser user = new SysUser();
        user.setUserId(userId);
        user.setNickName(nickName);
        user.setEmail(email);
        user.setPassword(DigestUtil.md5Hex(password));
        user.setCreateTime(DateUtil.toLocalDateTime(new Date()));
        user.setStatus(Constants.ENABLE);
        RegisterToSendEmails registerToSendEmails = redisComponent.getRegisterToSendEmails();
        userInfo.setTotalSpace(registerToSendEmails.getUserInitUseSpace() * Constants.MB);
        userInfo.setUseSpace(0L);
        userMapper.insert(userInfo);
    }

    @Override
    public SessionWebUserConfig login(String email, String password) {
        SysUser user = getUserByEmail(email);
        if (ObjUtil.isEmpty(user) || !user.getPassword().equals(password)) {
            throw new BusinessException("账号或者密码错误");
        }
        if (Constants.DISABLE.equals(user.getStatus())) {
            throw new BusinessException("账号已禁用");
        }
        user.setLastLoginTime(DateUtil.toLocalDateTime(new Date()));
        userMapper.updateById(user);
        SessionWebUserConfig sessionWebUserConfig = new SessionWebUserConfig();
        sessionWebUserConfig.setNickName(user.getNickName());
        sessionWebUserConfig.setUserId(user.getUserId());
        sessionWebUserConfig.setIsAdmin(ArrayUtils.contains(appConfig.getAdminEmails().split(","), email));
        //每次登录时从数据库查询用户空间
        UserSpaceConfig userSpaceConfig = new UserSpaceConfig();
        userSpaceConfig.setUseSpace(fileInfoService.getUserUseSpace(user.getUserId()));
        userSpaceConfig.setTotalSpace(user.getTotalSpace());
        //将用户空间信息保存在redis，并有一天的到期的时间
        redisComponent.saveUserSpaceUse(user.getUserId(), userSpaceConfig);
        return sessionWebUserConfig;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetPwd(String email, String password, String emailCode) {
        SysUser user = getUserByEmail(email);
        if (ObjUtil.isEmpty(user)) {
            throw new BusinessException("邮箱账号不存在");
        }
        //校验邮箱验证码
        verificationCodeMapper.checkCode(email, emailCode);
        user.setPassword(DigestUtil.md5Hex(password));
        userMapper.updateById(user);
    }
}
